package org.box.metadata.shell.web.server;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.collections.buffer.CircularFifoBuffer;
import org.box.metadata.cli.annotation.Command;
import org.box.metadata.shell.CommandHandler;
import org.box.metadata.shell.CommandHandlerListener;
import org.box.metadata.shell.web.WebShell;

public class ShellOutStream implements CommandHandlerListener{
	
	private final static Logger LOG = Logger.getLogger(ShellOutStream.class.getName());
	
	private long rowindex;
	ByteArrayOutputStream byteStream;
	//FIXME: LogRecored[] buffer;
	private final CircularFifoBuffer buffer;
	private final WebShell shell;

	public ShellOutStream(WebShell shell, int bufferSize) {
		this.shell = shell;
		byteStream = new ByteArrayOutputStream(bufferSize);
		buffer = new CircularFifoBuffer(bufferSize);
	}
	
	public PrintStream getPrintStream() {
		return new PrintStream(byteStream);
	}
	
	@SuppressWarnings("unchecked")
	public LogRecord[] getRecords() {
		updatedBuffer(shell.getCurrentSession());
		return (LogRecord[]) buffer.toArray(new LogRecord[0]);
	}
	
	//FIXME: use System.copyarray to shift the buffer.
	protected void updatedBuffer(String session) {
		String[] lines = null;
        synchronized (byteStream) {
        	String str = byteStream.toString();
        	if (str.length() > 0)
        		lines = byteStream.toString().split("\n");
        	byteStream.reset();
        }
	        
        if (lines != null)
	        for (String msg : lines) {
	        	if (LOG.isLoggable(Level.FINE))
	        		LOG.fine("Session: " + session + "; " + msg);
	        	buffer.add(new LogRecord(rowindex++, msg, session));
	        }
        
	}


	@Override
	public void onHandlerStart(CommandHandler<?> handler, Command c,Object cfg) {
		updatedBuffer(shell.getCurrentSession());
	}

	@Override
	public void onHandlerSuccess(CommandHandler<?> handler, Command c, Object cfg) {
		updatedBuffer(shell.getCurrentSession());
	}

	@Override
	public void onHandlerFailure(CommandHandler<?> handler, Command c, Object cfg) {
		updatedBuffer(shell.getCurrentSession());
	}

	
}